package com.example.performance.cli;

import org.apache.commons.cli.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 命令行参数解析器
 * 处理用户输入的命令行参数
 */
public class CommandLineParser {

    private static final Logger logger = LoggerFactory.getLogger(CommandLineParser.class);

    private final Options options;

    public CommandLineParser() {
        this.options = createOptions();
    }

    /**
     * 创建命令行选项
     * 
     * @return 选项对象
     */
    private Options createOptions() {
        Options opts = new Options();

        // 配置文件选项
        Option configOption = Option.builder("c")
                .longOpt("config")
                .hasArg()
                .argName("file")
                .desc("指定配置文件路径 (YAML或JSON格式)")
                .build();
        opts.addOption(configOption);

        // 并发用户数选项
        Option usersOption = Option.builder("u")
                .longOpt("users")
                .hasArg()
                .argName("number")
                .desc("并发用户数 (默认: 1)")
                .build();
        opts.addOption(usersOption);

        // 测试持续时间选项
        Option durationOption = Option.builder("d")
                .longOpt("duration")
                .hasArg()
                .argName("seconds")
                .desc("测试持续时间（秒） (默认: 60)")
                .build();
        opts.addOption(durationOption);

        // 预热时间选项
        Option rampUpOption = Option.builder("r")
                .longOpt("rampup")
                .hasArg()
                .argName("seconds")
                .desc("预热时间（秒） (默认: 0)")
                .build();
        opts.addOption(rampUpOption);

        // QPS限制选项
        Option qpsOption = Option.builder("q")
                .longOpt("qps")
                .hasArg()
                .argName("number")
                .desc("每秒请求数限制 (默认: 无限制)")
                .build();
        opts.addOption(qpsOption);

        // 报告格式选项
        Option formatOption = Option.builder("f")
                .longOpt("format")
                .hasArg()
                .argName("format")
                .desc("报告输出格式: console, json, html, csv (默认: console)")
                .build();
        opts.addOption(formatOption);

        // 输出路径选项
        Option outputOption = Option.builder("o")
                .longOpt("output")
                .hasArg()
                .argName("path")
                .desc("报告输出路径 (默认: ./results)")
                .build();
        opts.addOption(outputOption);

        // URL选项（快速测试模式）
        Option urlOption = Option.builder()
                .longOpt("url")
                .hasArg()
                .argName("url")
                .desc("快速测试模式：直接指定测试URL")
                .build();
        opts.addOption(urlOption);

        // 请求方法选项
        Option methodOption = Option.builder()
                .longOpt("method")
                .hasArg()
                .argName("method")
                .desc("HTTP请求方法 (默认: GET)")
                .build();
        opts.addOption(methodOption);

        // 请求头选项
        Option headerOption = Option.builder("H")
                .longOpt("header")
                .hasArgs()
                .valueSeparator('=')
                .argName("key=value")
                .desc("添加HTTP请求头，格式: key=value")
                .build();
        opts.addOption(headerOption);

        // 请求体选项
        Option bodyOption = Option.builder()
                .longOpt("data")
                .hasArg()
                .argName("data")
                .desc("HTTP请求体数据")
                .build();
        opts.addOption(bodyOption);

        // 验证配置选项
        Option validateOption = Option.builder()
                .longOpt("validate")
                .desc("仅验证配置文件，不执行测试")
                .build();
        opts.addOption(validateOption);

        // 生成示例配置选项
        Option exampleOption = Option.builder()
                .longOpt("example")
                .hasArg()
                .argName("file")
                .desc("生成示例配置文件")
                .build();
        opts.addOption(exampleOption);

        // 版本信息选项
        Option versionOption = Option.builder("v")
                .longOpt("version")
                .desc("显示版本信息")
                .build();
        opts.addOption(versionOption);

        // 帮助选项
        Option helpOption = Option.builder("h")
                .longOpt("help")
                .desc("显示帮助信息")
                .build();
        opts.addOption(helpOption);

        return opts;
    }

    /**
     * 解析命令行参数
     * 
     * @param args 命令行参数数组
     * @return 解析结果
     */
    public ParseResult parse(String[] args) {
        DefaultParser parser = new DefaultParser();

        try {
            CommandLine cmd = parser.parse(options, args);
            return new ParseResult(cmd, true, null);
        } catch (ParseException e) {
            logger.error("命令行参数解析失败: {}", e.getMessage());
            return new ParseResult(null, false, e.getMessage());
        }
    }

    /**
     * 打印帮助信息
     */
    public void printHelp() {
        HelpFormatter formatter = new HelpFormatter();
        formatter.setWidth(100);

        System.out.println();
        System.out.println("HTTP性能压测工具 v1.0.0");
        System.out.println("========================================");
        System.out.println();

        formatter.printHelp("java -jar http-performance-tester.jar [OPTIONS]",
                "基于场景的HTTP性能压测工具\n\n选项说明:",
                options,
                "\n使用示例:\n" +
                        "  java -jar http-performance-tester.jar -c config.yml\n" +
                        "  java -jar http-performance-tester.jar --url https://api.example.com -u 10 -d 60\n" +
                        "  java -jar http-performance-tester.jar --example example.yml\n");
        System.out.println();
    }

    /**
     * 打印版本信息
     */
    public void printVersion() {
        System.out.println("HTTP Performance Tester v1.0.0");
        System.out.println("基于JDK 1.8开发的HTTP性能压测工具");
        System.out.println("Copyright (c) 2024");
    }

    /**
     * 解析结果封装类
     */
    public static class ParseResult {
        private final CommandLine commandLine;
        private final boolean success;
        private final String errorMessage;

        public ParseResult(CommandLine commandLine, boolean success, String errorMessage) {
            this.commandLine = commandLine;
            this.success = success;
            this.errorMessage = errorMessage;
        }

        public CommandLine getCommandLine() {
            return commandLine;
        }

        public boolean isSuccess() {
            return success;
        }

        public String getErrorMessage() {
            return errorMessage;
        }

        /**
         * 检查是否有指定选项
         * 
         * @param option 选项名
         * @return 是否存在
         */
        public boolean hasOption(String option) {
            return success && commandLine.hasOption(option);
        }

        /**
         * 获取选项值
         * 
         * @param option 选项名
         * @return 选项值
         */
        public String getOptionValue(String option) {
            return success ? commandLine.getOptionValue(option) : null;
        }

        /**
         * 获取选项值，带默认值
         * 
         * @param option       选项名
         * @param defaultValue 默认值
         * @return 选项值或默认值
         */
        public String getOptionValue(String option, String defaultValue) {
            return success ? commandLine.getOptionValue(option, defaultValue) : defaultValue;
        }

        /**
         * 获取选项值数组
         * 
         * @param option 选项名
         * @return 选项值数组
         */
        public String[] getOptionValues(String option) {
            return success ? commandLine.getOptionValues(option) : null;
        }

        /**
         * 获取整数类型的选项值
         * 
         * @param option       选项名
         * @param defaultValue 默认值
         * @return 整数值
         */
        public int getIntOptionValue(String option, int defaultValue) {
            if (!success)
                return defaultValue;

            String value = commandLine.getOptionValue(option);
            if (value == null)
                return defaultValue;

            try {
                return Integer.parseInt(value);
            } catch (NumberFormatException e) {
                logger.warn("选项 {} 的值 {} 不是有效的整数，使用默认值 {}", option, value, defaultValue);
                return defaultValue;
            }
        }
    }
}